package com.css.fxfzfxqh.modules.earthquakeRiskAssessmentZoningReport.service;

import cn.hutool.core.util.IdUtil;
import com.css.fxfzfxqh.constants.YNEnum;
import com.css.fxfzfxqh.modules.buildingKilometerGrid.exceptions.BizException;
import com.css.fxfzfxqh.modules.buildings.definitiveEvaluation.casualtiesDE.param.CasualtiesDECalculationParam;
import com.css.fxfzfxqh.modules.buildings.definitiveEvaluation.casualtiesDE.service.CasualtiesDEService1;
import com.css.fxfzfxqh.modules.buildings.definitiveEvaluation.economicLossDE.param.EconomicLossParam;
import com.css.fxfzfxqh.modules.buildings.definitiveEvaluation.economicLossDE.service.EconomicLossEDService;
import com.css.fxfzfxqh.modules.buildings.definitiveEvaluation.resistEarthquakesDE.param.ResistEarthquakesCalculationParam;
import com.css.fxfzfxqh.modules.buildings.definitiveEvaluation.resistEarthquakesDE.service.ResistEarthquakesDEService;
import com.css.fxfzfxqh.modules.buildings.probabilityEvaluation.casualtiesPE.param.CasualtiesPECalculationParam;
import com.css.fxfzfxqh.modules.buildings.probabilityEvaluation.casualtiesPE.service.CasualtiesPEService;
import com.css.fxfzfxqh.modules.buildings.probabilityEvaluation.economicLossPE.param.EconomicLossPECalculationParam;
import com.css.fxfzfxqh.modules.buildings.probabilityEvaluation.economicLossPE.service.EconomicLossPDService;
import com.css.fxfzfxqh.modules.buildings.probabilityEvaluation.resistEarthquakesPE.param.ResistEarthquakesPECalculationParam;
import com.css.fxfzfxqh.modules.buildings.probabilityEvaluation.resistEarthquakesPE.service.ResistEarthquakesPEService;
import com.css.fxfzfxqh.modules.comprehensiveSearch.dto.CalculationResultListDto;
import com.css.fxfzfxqh.modules.comprehensiveSearch.service.CalculationResultService;
import com.css.fxfzfxqh.modules.earthquakeRiskAssessmentZoningReport.model.dto.FxqhAssessReportBuildReportDto;
import com.css.fxfzfxqh.modules.earthquakeRiskAssessmentZoningReport.model.entity.FxqhAssessReport;
import com.css.fxfzfxqh.modules.earthquakeRiskAssessmentZoningReport.model.entity.FxqhAssessReportRecord;
import com.css.fxfzfxqh.modules.earthquakeRiskAssessmentZoningReport.model.vo.FxqhAssessReportListVo;
import com.css.fxfzfxqh.modules.earthquakeRiskAssessmentZoningReport.param.AssessExportParam;
import com.css.fxfzfxqh.modules.earthquakeRiskAssessmentZoningReport.repository.FxqhAssessReportRecordRepository;
import com.css.fxfzfxqh.modules.earthquakeRiskAssessmentZoningReport.repository.FxqhAssessReportRepository;
import com.css.fxfzfxqh.modules.singleIndexRiskZoning.param.QhSingleExportParam;
import com.css.fxfzfxqh.modules.singleIndexRiskZoning.service.EnterAssessQhService;
import com.css.fxfzfxqh.modules.singleIndexRiskZoning.service.ProbabilityAssessQhService;
import com.css.fxfzfxqh.modules.synthesis.param.QhSynthesisExportParam;
import com.css.fxfzfxqh.modules.synthesis.service.AssessService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Transactional(rollbackFor = Exception.class)
@Slf4j
public class FxqhAssessReportService {
    @Autowired
    private FxqhAssessReportRepository fxqhAssessReportRepository;
    @Autowired
    private FxqhAssessReportRecordRepository fxqhAssessReportRecordRepository;
    @Autowired
    private CalculationResultService calculationResultService;
    @Resource
    ResistEarthquakesDEService resistEarthquakesDEService;
    @Resource
    CasualtiesDEService1 casualtiesDEService1;
    @Resource
    EconomicLossEDService economicLossEDService;
    @Resource
    ResistEarthquakesPEService resistEarthquakesPEService;
    @Resource
    CasualtiesPEService casualtiesPEService;
    @Resource
    EconomicLossPDService economicLossPDService;
    @Resource
    EnterAssessQhService enterAssessQhService;
    @Resource
    ProbabilityAssessQhService probabilityAssessQhService;
    @Resource
    AssessService assessService;
    private static final String REPORT_CODE_PREFIX = "FXBG";

    public synchronized String buildReportCode() {
        String code = fxqhAssessReportRepository.getLatestTemplateCode();
        if (StringUtils.isBlank(code)) {
            code = "0";
        }
        int num = Integer.parseInt(code.replaceAll(REPORT_CODE_PREFIX, "")) + 1;
        return REPORT_CODE_PREFIX + (num < 100 ? (num < 10 ? "00" + num : "0" + num) : num);
    }

    public synchronized void buildReport(FxqhAssessReportBuildReportDto dto) throws BizException {
        Integer count = fxqhAssessReportRepository.countByCode(dto.getCode());
        if (count != 0) {
            throw new BizException("报告模板编号已被其他模板占用，请刷新页面后重试");
        }
        FxqhAssessReport fxqhAssessReport = new FxqhAssessReport();
        BeanUtils.copyProperties(dto, fxqhAssessReport);
        String reportId = IdUtil.getSnowflakeNextIdStr();
        fxqhAssessReport.setId(reportId);
        fxqhAssessReport.setDelFlag(YNEnum.N.toString());
        fxqhAssessReport.setFileId(this.buildReportFile(dto));
        fxqhAssessReportRecordRepository.batchSave(dto.getRecordIds().stream().map(o -> {
            FxqhAssessReportRecord fxqhAssessReportRecord = new FxqhAssessReportRecord();
            fxqhAssessReportRecord.setId(IdUtil.getSnowflakeNextIdStr());
            fxqhAssessReportRecord.setReportId(reportId);
            fxqhAssessReportRecord.setRecordId(o);
            return fxqhAssessReportRecord;
        }).collect(Collectors.toList()));
        fxqhAssessReportRepository.insert(fxqhAssessReport);
    }

    /**
     * TODO 生成报告
     *
     * @param dto
     * @return
     */
    private String buildReportFile(FxqhAssessReportBuildReportDto dto) {
        return "94431df7b8f5403c9bb24def81adde06";
    }

    /**
     * @param code
     * @param name
     * @return
     */
    public List<FxqhAssessReportListVo> list(String code, String name) {
        List<FxqhAssessReport> list = fxqhAssessReportRepository.list(code, name);
        if (list == null) {
            return null;
        }
        return list.stream().map(o -> {
            FxqhAssessReportListVo vo = new FxqhAssessReportListVo();
            BeanUtils.copyProperties(o, vo);
            List<String> resultListDtos = new ArrayList<>();
            for (String recordId : o.getRecords()) {
                CalculationResultListDto recordDto = calculationResultService.getById(recordId);
                if (recordDto != null) {
                    resultListDtos.add(recordDto.getAssessCode());
                }
            }
            if (!CollectionUtils.isEmpty(resultListDtos)) {
                vo.setRecordCodes(StringUtils.join(resultListDtos, "、"));
            }
            return vo;
        }).collect(Collectors.toList());
    }

    public void delete(String id, String uid) {
        fxqhAssessReportRepository.delete(id, uid, new Date());
    }

    public void upload(String templateId, String fileId, String uid) {
        fxqhAssessReportRepository.upload(templateId, fileId, uid, new Date());
    }

    public void exportData(HttpServletResponse response, AssessExportParam param) {
        //任务id
        String taskId = param.getId();
        //省
        String province = param.getProvince();
        //市
        String city = param.getCity();
        //县
        String county = param.getCounty();
        //0评估/1区划
        String dataType = param.getAssessAndQh();
        if ("0".equals(dataType)) {
            //评估方式 0为确定评估1为概率评估
            String assessType = param.getAssessType();
            //评估对象0为结构破坏,1为人员受伤,2为人员死亡,3为经济损失
            String assessObj = param.getAssessObj();
            //地震输入方式0为设定烈度1为四个概率,2为地震影响场,  3为发生概率危险性,4为超越概率危险性
            String seismicInputMode = param.getSeismicInputMode();
            if ("0".equals(assessType)) {
                //确定评估：烈度时（ld1，ld2，ld3，ld4，ld5）；4个概率水准时（sgglsz1、sgglsz2、sgglsz3、sgglsz4）
                String condition = param.getCondition();
                if ("0".equals(assessObj)) {
                    //破坏程度
                    String damageDegree=param.getDamageDegree();
                    ResistEarthquakesCalculationParam param1 = new ResistEarthquakesCalculationParam();
                    param1.setId(taskId);
                    param1.setSeismicInputMode(seismicInputMode);
                    param1.setCondition(condition);
                    param1.setDamageDegree(damageDegree);
                    param1.setProvince(province);
                    param1.setCity(city);
                    param1.setCounty(county);
                    resistEarthquakesDEService.exportData(response, param1);
                } else if ("1".equals(assessObj) || "2".equals(assessObj)) {
                    //时间段(白天晚上)
                    String time=param.getTime();
                    CasualtiesDECalculationParam param1 = new CasualtiesDECalculationParam();
                    param1.setId(taskId);
                    param1.setSeismicInputMode(seismicInputMode);
                    param1.setCondition(condition);
                    if ("1".equals(assessObj)) {
                        param1.setCasualties("rysw1");
                    } else {
                        param1.setCasualties("rysw2");
                    }
                    param1.setTime(time);
                    param1.setProvince(province);
                    param1.setCity(city);
                    param1.setCounty(county);
                    casualtiesDEService1.exportData(response, param1);
                } else if ("3".equals(assessObj)) {
                    EconomicLossParam param1 = new EconomicLossParam();
                    param1.setId(taskId);
                    param1.setSeismicInputMode(seismicInputMode);
                    param1.setCondition(condition);
                    param1.setProvince(province);
                    param1.setCity(city);
                    param1.setCounty(county);
                    economicLossEDService.exportData(response, param1);
                }
            } else if ("1".equals(assessType)) {
                //概率评估：T年
                String year = param.getYear();
                if ("0".equals(assessObj)) {
                    //破坏程度
                    String damageDegree=param.getDamageDegree();
                    ResistEarthquakesPECalculationParam param1 = new ResistEarthquakesPECalculationParam();
                    param1.setId(taskId);
                    param1.setSeismicInputMode(seismicInputMode);
                    param1.setYears(year);
                    param1.setDamageDegree(damageDegree);
                    param1.setProvince(province);
                    param1.setCity(city);
                    param1.setCounty(county);
                    resistEarthquakesPEService.exportData(response, param1);
                } else if ("1".equals(assessObj) || "2".equals(assessObj)) {
                    //时间段(白天晚上)
                    String time=param.getTime();
                    CasualtiesPECalculationParam param1 = new CasualtiesPECalculationParam();
                    param1.setId(taskId);
                    param1.setSeismicInputMode(seismicInputMode);
                    param1.setYears(year);
                    if ("1".equals(assessObj)) {
                        param1.setCasualties("rysw1");
                    } else {
                        param1.setCasualties("rysw2");
                    }
                    param1.setTime(time);
                    param1.setProvince(province);
                    param1.setCity(city);
                    param1.setCounty(county);
                    casualtiesPEService.exportData(response, param1);
                } else if ("3".equals(assessObj)) {
                    EconomicLossPECalculationParam param1 = new EconomicLossPECalculationParam();
                    param1.setId(taskId);
                    param1.setSeismicInputMode(seismicInputMode);
                    param1.setYears(year);
                    param1.setProvince(province);
                    param1.setCity(city);
                    param1.setCounty(county);
                    economicLossPDService.exportData(response, param1);
                }
            }
        } else if ("1".equals(dataType)) {
            //评估方式 0为确定评估1为概率评估
            String assessType = param.getAssessType();
            //评估对象0为结构破坏,1为人员受伤,2为人员死亡,3为经济损失
            String assessObj = param.getAssessObj();
            //地震输入方式0为设定烈度1为四个概率,2为地震影响场,  3为发生概率危险性,4为超越概率危险性
            String seismicInputMode = param.getSeismicInputMode();
            //区划：0时单指标风险区划；1时综合指标风险区划
            String qhType = param.getQhType();
            if ("0".equals(qhType)) {
                if ("0".equals(assessType)) {
                    //确定评估：烈度时（ld1，ld2，ld3，ld4，ld5）；4个概率水准时（sgglsz1、sgglsz2、sgglsz3、sgglsz4）
                    String condition = param.getCondition();
                    QhSingleExportParam param1 = new QhSingleExportParam();
                    param1.setId(taskId);
                    param1.setAssessObj(assessObj);
                    param1.setSeismicInputMode(seismicInputMode);
                    param1.setCondition(condition);
                    param1.setProvince(province);
                    param1.setCity(city);
                    param1.setCounty(county);
                    enterAssessQhService.exportData(response, param1);
                } else if ("1".equals(assessType)) {
                    //概率评估：T年
                    String year = param.getYear();
                    QhSingleExportParam param1 = new QhSingleExportParam();
                    param1.setId(taskId);
                    param1.setAssessObj(assessObj);
                    param1.setSeismicInputMode(seismicInputMode);
                    param1.setYear(year);
                    param1.setProvince(province);
                    param1.setCity(city);
                    param1.setCounty(county);
                    probabilityAssessQhService.exportData(response, param1);
                }
            } else if ("1".equals(qhType)) {
                if ("0".equals(assessType)) {
                    //确定评估：烈度时（ld1，ld2，ld3，ld4，ld5）；4个概率水准时（sgglsz1、sgglsz2、sgglsz3、sgglsz4）
                    String condition = param.getCondition();
                    QhSynthesisExportParam param1 = new QhSynthesisExportParam();
                    param1.setId(taskId);
                    param1.setAssessType("0");
                    param1.setCategory(seismicInputMode);
                    param1.setType(condition);
                    param1.setProvince(province);
                    param1.setCity(city);
                    param1.setCounty(county);
                    assessService.exportData(response, param1);
                } else if ("1".equals(assessType)) {
                    //概率评估：T年
                    String year = param.getYear();
                    QhSynthesisExportParam param1 = new QhSynthesisExportParam();
                    param1.setId(taskId);
                    param1.setAssessType("1");
                    param1.setCategory(seismicInputMode);
                    param1.setType(year);
                    param1.setProvince(province);
                    param1.setCity(city);
                    param1.setCounty(county);
                    assessService.exportData(response, param1);
                }
            }
        }
    }


}
